package org.oos.atom;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.oos.auth.AbstractAuthentication.pack;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.oos.atom.AtomService.HttpStatusException;
import org.oos.auth.AuthenticationHandler;
import org.oos.dao.options.OptionsMap;
import org.oos.util.Log;

import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpContent;
import com.google.api.client.http.HttpMethod;
import com.google.api.client.http.HttpParser;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.apache.ApacheHttpTransport;

public class AtomRequest {

	private final GenericUrl url;
	private final AuthenticationHandler authHandler;
	private final HttpMethod httpMethod;
	private final HttpParser httpParser;
	private final HttpContent content;
	private final List<OptionsMap> parameters;
	private static final HttpTransport transport = new ApacheHttpTransport();

	public static Builder requestBuilder() {
		return new Builder();
	}
	
	protected HttpResponse getHttpResponse() throws IOException, HttpStatusException {
		Log.i(httpMethod.name() + ": " + pack(url, parameters).toString());
			
			return authHandler.getResponse(transport, url, httpMethod, content,
					parameters, httpParser);
		
	}

	public static class Builder {

		private GenericUrl url;
		private AuthenticationHandler authHandler;
		private HttpMethod httpMethod;
		private HttpParser httpParser;
		private HttpContent content;
		private List<OptionsMap> parameters;

		private Builder() {
		}

		public AtomRequest build() {
			return new AtomRequest(url, authHandler, httpMethod, httpParser,
					content, parameters);
		}

		/**
		 * @param url
		 *            the url to set
		 */
		public Builder setUrl(GenericUrl url) {
			this.url = url;
			return this;
		}

		/**
		 * @param authHandler
		 *            the authHandler to set
		 */
		public Builder setAuthHandler(AuthenticationHandler authHandler) {
			this.authHandler = authHandler;
			return this;
		}

		/**
		 * @param httpMethod
		 *            the httpMethod to set
		 */
		public Builder setHttpMethod(HttpMethod httpMethod) {
			this.httpMethod = httpMethod;
			return this;
		}

		/**
		 * @param httpParser
		 *            the httpParser to set
		 */
		public Builder setHttpParser(HttpParser httpParser) {
			this.httpParser = httpParser;
			return this;
		}

		/**
		 * @param content
		 *            the content to set
		 */
		public Builder setContent(HttpContent content) {
			this.content = content;
			return this;
		}

		/**
		 * @param parameters
		 *            the parameters to set
		 */
		public Builder setParameters(List<OptionsMap> parameters) {
			this.parameters = parameters;
			return this;
		}
		
	}

	private AtomRequest(GenericUrl url, AuthenticationHandler authHandler,
			HttpMethod httpMethod, HttpParser httpParser, HttpContent content,
			List<OptionsMap> parameters) {
		super();
		checkNotNull(authHandler);
		checkNotNull(url);
		checkNotNull(httpParser);
		this.url = url;
		this.authHandler = authHandler;
		this.httpMethod = httpMethod;
		this.httpParser = httpParser;
		this.content = content;
		this.parameters = parameters;
	}

	/**
	 * @return the url
	 */
	public GenericUrl getUrl() {
		return url;
	}

	/**
	 * @return the authHandler
	 */
	public AuthenticationHandler getAuthHandler() {
		return authHandler;
	}

	/**
	 * @return the httpMethod
	 */
	public HttpMethod getHttpMethod() {
		return httpMethod;
	}

	/**
	 * @return the httpParser
	 */
	public HttpParser getHttpParser() {
		return httpParser;
	}

	/**
	 * @return the content
	 */
	public HttpContent getContent() {
		return content;
	}

	/**
	 * @return the parameters
	 */
	public List<OptionsMap> getParameters() {
		return parameters;
	}

}
